package io.terminus.lego.shinda.web.security.handler

import io.terminus.lego.shinda.service.model.toDTO
import io.terminus.lego.shinda.service.service.UserService
import io.terminus.lego.shinda.web.context.UserContext
import org.springframework.security.core.Authentication
import org.springframework.security.web.authentication.SavedRequestAwareAuthenticationSuccessHandler
import org.springframework.security.web.savedrequest.HttpSessionRequestCache
import org.springframework.security.web.savedrequest.RequestCache
import org.springframework.stereotype.Component
import org.springframework.util.StringUtils
import java.io.IOException
import javax.servlet.ServletException
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
 * 登录成功处理
 * @author wangmeng
 * @date 2018/4/12
 */
@Component
class UCAuthenticationSuccessHandler constructor(val userService: UserService) : SavedRequestAwareAuthenticationSuccessHandler() {
    /**
     * 默认登录成功时会302到成功页，我们要让其直接返回json，因此转发到success接口
     */
    private val handleSuccessPath = "/api/login/success"

    private val requestCache: RequestCache = HttpSessionRequestCache()

    @Throws(IOException::class, ServletException::class)
    override fun onAuthenticationSuccess(request: HttpServletRequest, response: HttpServletResponse, authentication: Authentication) {

        //写用户进session，对于内部系统单点登录，在此处将用户信息写到session中，其他系统与uc共享session即可

        //TODO Oauth2登录目前不走这个处理器,暂时无法设置session
        val user = userService.findUserByUsername(authentication.name)
                ?: throw RuntimeException("用户缺少username信息")
        val userDto = user.toDTO()
        request.session.setAttribute(UserContext.SESSION_KEY, userDto)
        UserContext.setCurrentUser(userDto)

        //获取为登录前保存的请求地址
        val savedRequest = requestCache.getRequest(request, response)
        if (savedRequest != null) {
            //检查是否总是跳转到默认目标页
            val targetUrlParameter = targetUrlParameter
            if (isAlwaysUseDefaultTargetUrl || targetUrlParameter != null && StringUtils.hasText(request.getParameter(targetUrlParameter))) {
                requestCache.removeRequest(request, response)
                super.onAuthenticationSuccess(request, response, authentication)
                return
            }
            clearAuthenticationAttributes(request)
            // Use the DefaultSavedRequest URL
            val targetUrl = savedRequest.redirectUrl
            logger.debug("Redirecting to DefaultSavedRequest Url: " + targetUrl)
            request.setAttribute("redirectUrl", targetUrl)
        }

        request.getRequestDispatcher(handleSuccessPath).forward(request, response)


    }
}